package com.sunday.common.core.lambda;

import com.sunday.common.core.lambda.toolkit.LambdaUtils;
import com.sunday.common.core.lambda.toolkit.support.ColumnMapper;
import com.sunday.common.core.lambda.toolkit.support.LambdaMeta;
import com.sunday.common.core.lambda.toolkit.support.SFunction;
import com.sunday.common.core.utils.StringUtils;

import java.util.Map;
import java.util.Optional;

/**
 * lambda operation
 *
 * @author zsy
 * @since 2024/1/16
 */
public interface ColumnMapperOperation extends LambdaOperation {

    /**
     * 通过 function 获取 字段注解内容
     *
     * @param func
     * @return {@link String}
     */
    @Override
    default <T> String getColumnName(SFunction<T, ?> func) {
        return getColumnName(LambdaUtils.extract(func));
    }

    /**
     * 通过 lambdaMeta(SerializedLambda) 获取 字段注解内容
     *
     * @param lambdaMeta
     * @return {@link String}
     */
    private String getColumnName(LambdaMeta lambdaMeta) {
        String fieldName = StringUtils.resolveFieldName(lambdaMeta.implMethodName());
        Class<?> target = lambdaMeta.instantiatedClass();
        return getColumnName(target, fieldName);
    }

    /**
     * 通过类和属性名 获取 字段注解内容 (未匹配则返回 fieldName)
     *
     * @param target
     * @param fieldName
     * @return {@link String}
     */
    default String getColumnName(Class<?> target, String fieldName) {
        return Optional.ofNullable(getColumnAdapter(target).get(fieldName))
                .map(ColumnMapper::getColumnSelect)
                .orElse(fieldName);
    }

    /**
     * 通过 class 获取缓存map是否存在，不存在则构建
     *
     * @param target
     * @return {@link Map< String, ColumnMapper>}
     */
    default Map<String, ColumnMapper> getColumnAdapter(Class<?> target) {
        return Optional.ofNullable(getColumnMap(target))
                .orElseGet(() -> createColumnMap(target));
    }

    /**
     * 通过 class 获取 已生成的类字段缓存信息
     *
     * @param target
     * @return {@link Map< String, ColumnMapper>}
     */
    Map<String, ColumnMapper> getColumnMap(Class<?> target);

    /**
     * 通过 class 创建 类字段缓存信息
     *
     * @param target
     * @return {@link Map< String, ColumnMapper>}
     */
    Map<String, ColumnMapper> createColumnMap(Class<?> target);

}
